"""
分页组件
使用方法
    page_object = Pagination(request, queryset)
    html_text = page_object.html()
    page_query_set = page_object.page_query_set
    context = {
        'query_set': page_query_set, #返回当页的数据集
        'page_html': html_text, #返回页码html标签
        'query_str': query_str, #返回查询的字符串，同页码组件不是强关联，根据需要设置
    }
html页面中
# 显示当前页数据
{% for item in query_set %}
中间加入需要显示的字段内容
{% endfor %}
# 分页添加到页面末尾
{{ page_html }}
"""
import copy

from django.utils.html import mark_safe


class Pagination(object):

    def __init__(self, request, queryset, page_param="page", plus=5, record=10):
        """
        plus:显示当前页的前后plus个页签，即总共显示plus*2+1页
        record:每页显示的记录数
        page_param:传递的页码参数名称
        request:传递的请求类，用于获取page参数
        queryset:数据集参数
        """
        # 获得当前页数
        page = request.GET.get('page', '1')
        if page.isdecimal():
            page = int(page)
        else:
            page = 1
        # 记录总数量
        total_count = queryset.count()
        # 计算总页数
        total_page = total_count // record + 1
        # 设置参数列表
        page_param_list = copy.deepcopy(request.GET)
        page_param_list._mutable = True
        self.page_param_list = page_param_list

        # 设置参数名称
        self.page_param = page_param

        # 设置类变量 total_page
        self.total_page = total_page

        # 如果输入的页码超出最大页码范围，则显示最后一页
        if page > total_page:
            page = total_page
        # 设置类变量 page
        self.page = page

        # 获得数据集
        page_query_set = queryset[(page - 1) * record:page * record + 1]

        # 设置开始页和结束页
        if total_page < plus * 2 + 1:
            start = 1
            end = total_page
        else:
            if page <= plus:
                start = 1
                end = plus * 2 + 1
            elif page >= total_page - plus:
                start = total_page - plus * 2
                end = total_page
            else:
                start = page - plus
                end = page + plus

        # 设置类变量start 和 end
        self.start = start
        self.end = end

        # 设置当前页显示的查询结果
        self.page_query_set = page_query_set

    @property
    def html(self):
        # 生成页码html
        self.page_param_list.setlist(self.page_param, [1])
        page_html = ['<div class="clearfix"><ul class="pagination">',
                     '<li><a href="?{}">{}</a></li>'.format(self.page_param_list.urlencode(), '首页')]
        # 首页
        # 上一页
        prev_page = self.page - 1 if self.page > 1 else 1
        self.page_param_list.setlist(self.page_param, [prev_page])
        page_html.append('<li><a href="?{}">{}</a></li>'.format(self.page_param_list.urlencode(), '上一页'))
        for i in range(self.start, self.end + 1):
            if i == self.page:
                self.page_param_list.setlist(self.page_param, [i])
                page_html.append('<li class="active"><a href="?{}">{}</a></li>'.format(self.page_param_list.urlencode(), i))
                continue
            self.page_param_list.setlist(self.page_param, [i])
            page_html.append('<li><a href="?{}">{}</a></li>'.format(self.page_param_list.urlencode(), i))

        # 下一页
        next_page = self.page + 1 if self.page < self.total_page else self.total_page
        self.page_param_list.setlist(self.page_param, [next_page])
        page_html.append('<li><a href="?{}">{}</a></li>'.format(self.page_param_list.urlencode(), '下一页'))
        # 尾页
        self.page_param_list.setlist(self.page_param, [self.total_page])
        page_html.append('<li><a href="?{}">{}</a></li>'.format(self.page_param_list.urlencode(), '尾页'))
        page_search_str = """
            <li><form style="float:left; margin-left:10px; width:150px" method="GET">
            <div class="input-group">
              <input type="text" name="page" class="form-control" placeholder="跳转到...">
              <span class="input-group-btn">
                <button class="btn btn-default" type="submit">跳转</button>
              </span>
            </div>
            </form></li>
        """
        page_html.append(page_search_str)
        page_html.append('</ul></div>')
        page_html_str = ''.join(page_html)
        html_text = mark_safe(page_html_str)
        return html_text
